package com.jmu.edu.IMApplication;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;


import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.google.android.material.imageview.ShapeableImageView;
import com.google.android.material.tabs.TabLayout;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jmu.edu.IMApplication.adapter.MainPageViewAdapter;
import com.jmu.edu.IMApplication.animation.AccordionTransformer;
import com.jmu.edu.IMApplication.bean.ButtonMessage;
import com.jmu.edu.IMApplication.bean.ChatRecord;
import com.jmu.edu.IMApplication.bean.Emoji;
import com.jmu.edu.IMApplication.bean.EmojiList;
import com.jmu.edu.IMApplication.bean.GestureAndFaceResult;
import com.jmu.edu.IMApplication.event.RefreshEvent;
import com.jmu.edu.IMApplication.fragment.ChatFragment;
import com.jmu.edu.IMApplication.fragment.CustomTextFragment;
import com.jmu.edu.IMApplication.fragment.FriendNotificationFragment;
import com.jmu.edu.IMApplication.fragment.LoginFragment;
import com.jmu.edu.IMApplication.fragment.SearchFriendFragment;
import com.jmu.edu.IMApplication.fragment.ShowTagFragment;
import com.jmu.edu.IMApplication.gen.ChatRecordDao;
import com.jmu.edu.IMApplication.myview.NoScrollViewPager;
import com.jmu.edu.IMApplication.net.bean.FriendInvite;
import com.jmu.edu.IMApplication.net.bean.Identify;
import com.jmu.edu.IMApplication.net.bean.UserIdentify;
import com.jmu.edu.IMApplication.utils.HttpUtil;
import com.jmu.edu.IMApplication.utils.LoginUtils;
import com.jmu.edu.IMApplication.utils.SystemUtil;
import com.jmu.edu.IMApplication.utils.ViewUtils;
import com.jmu.edu.IMApplication.utils.WillowUtils;
import com.nightonke.boommenu.BoomButtons.OnBMClickListener;
import com.nightonke.boommenu.BoomButtons.TextInsideCircleButton;
import com.nightonke.boommenu.BoomMenuButton;
import com.nightonke.boommenu.Util;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
import cn.jpush.im.android.api.event.LoginStateChangeEvent;
import cn.jpush.im.android.api.model.UserInfo;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "Main";
    private TextView nameText, signText;
    private ShapeableImageView avatarImage;
    private BoomMenuButton addButton;

    private NoScrollViewPager viewPager;
    private TabLayout tabLayout;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WillowUtils.registerEventReceiver(this);
        EventBus.getDefault().register(this);
        // 将整个Activity的事务管理者传进去作为全局变量使用
        MyApplication.fragmentManager = getSupportFragmentManager();
        viewPager = findViewById(R.id.main_viewpager);
        viewPager.setNoScroll(true);
        viewPager.setPageTransformer(true, new AccordionTransformer());
        tabLayout = findViewById(R.id.main_tab_layout);
        nameText = findViewById(R.id.main_username);
        signText = findViewById(R.id.main_sign);
        //addButton = findViewById(R.id.main_add);
        avatarImage = findViewById(R.id.main_avatar_image);
        getScreenWidthAndLength();
        //create后就要马上执行对BoomMenuButton的初始化
        initBoomMenuButton();
        //进来直接切换到登录界面，如果登录成功，则初始化数据
        showLoginFragment();


    }

    private void showLoginFragment() {
        LoginFragment loginFragment = new LoginFragment();
        ViewUtils.showFragment(loginFragment, "login");
    }

    private void showChatFragment(String username, String nickname) {
        String tag = "chat";
        ChatFragment chatFragment = (ChatFragment) MyApplication.fragmentManager.findFragmentByTag(tag);
        if (chatFragment == null) {
            chatFragment = new ChatFragment();
        }
        //传递必须的参数
        Bundle bundle = new Bundle();
        bundle.putString("username", username);
        bundle.putString("friendName", nickname);
        bundle.putString("state", "在线");
        chatFragment.setArguments(bundle);
        ViewUtils.showFragment(chatFragment, tag, R.anim.from_right, R.anim.out_right);
    }

    private void showFriendNotificationFragment() {
        String tag = "friendNotification";
        Fragment show = MyApplication.fragmentManager.findFragmentByTag(tag);
        if (show == null) {
            show = new FriendNotificationFragment();
        }
        ViewUtils.showFragment(show, tag, R.anim.from_right, R.anim.out_right);
    }

    @Override
    protected void onDestroy() {
        //杀死进程时是登录状态下的离线状态，调用logout才是未登录状态
        super.onDestroy();
    }

    @Subscribe
    public void onRefreshEvent(RefreshEvent event) {
        if (event.getTag().equals("main")) {
            fillViewWithValues(MyApplication.getUser());
        }
    }

    public void onEventMainThread(@NotNull LoginStateChangeEvent event) {
        //登陆状态变更事件
        Log.d("test", "onEvent: ");
        LoginStateChangeEvent.Reason reason = event.getReason();//获取变更的原因
        UserInfo myInfo = event.getMyInfo();//获取当前被登出账号的信息
        if (myInfo != null) {
            LoginUtils.logout();
        }
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setCancelable(false)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        reStartActivity();
                    }
                });

        switch (reason) {
            case user_password_change:
                alertDialogBuilder.setMessage("您的密码已经更改，请重新登录");
                break;
            case user_logout:
                alertDialogBuilder.setMessage("您的账号在其他设备上登录");
                Log.d("test", "onEventMainThread: " + LoginUtils.isLogin());
                break;
            case user_deleted:
                //用户被删除
                alertDialogBuilder.setMessage("您的账号被服务器删除！");
                break;
        }
        alertDialogBuilder.create().show();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        //用于点击横幅通知消息后的界面跳转
        super.onNewIntent(intent);
        setIntent(intent);
        if (!LoginUtils.isLogin()) {
            showLoginFragment();
        } else {
            String destFrag = intent.getStringExtra("destFrag");
            if (destFrag != null) {
                if (destFrag.equals("chat")) {
                    //跳转聊天界面
                    String username = intent.getStringExtra("username");
                    String nickname = intent.getStringExtra("nickname");
                    if (username != null) {
                        Log.d("test", "onNewIntent: " + username);
                        showChatFragment(username, nickname);
                    } else {
                        Log.d("test", "onNewIntent: username null");
                    }
                } else if (destFrag.equals("friendNotification")) {
                    //跳转好友通知碎片
                    showFriendNotificationFragment();
                    Log.d("test", "onNewIntent: friendNotification");
                }
            }
        }
        Log.d("test", "onNewIntent");
    }

    public void reStartActivity() {
        //重启app
        Log.d("test", "reStartActivity: ");
        Intent intent = getIntent();
        finish();
        startActivity(intent);

        //这是彻底的重启，模拟过程为：关闭app-重新打开app
//        Intent intent = getBaseContext().getPackageManager()
//                .getLaunchIntentForPackage(getBaseContext().getPackageName());
//        PendingIntent restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
//        AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//        mgr.set(AlarmManager.RTC, System.currentTimeMillis(), restartIntent); // 马上重启应用
//        System.exit(0);
    }

    /**
     * 登陆成功后调用
     * 初始化头像、姓名、个性签名数据
     * 初始化tablayout和viewpager内容
     * 初始化按钮监听
     */
    public void initView() {
        //获取用户的预设文本
        getIdentifyList();
        //获取用户的好友通知列表
        getFriendInviteList();
        //根据用户信息来填充昵称、签名以及头像
        fillViewWithValues(MyApplication.getUser());
        //初始化按钮监听
        initListener();
        //初始化tabLayout和viewpager内容
        initTabLayout();
        //登录成功后，先看一下有没有本地GreenDao的ChatRecord，如果没有的话，创建该数据表
        ChatRecord chatRecord = MyApplication.getChatRecordDao().queryBuilder()
                .where(ChatRecordDao.Properties.Username.eq(MyApplication.getUser().getUserName()))
                .unique();
        if (chatRecord == null) {
            chatRecord = new ChatRecord();
            chatRecord.setText("");
            chatRecord.setUsername(MyApplication.getUser().getUserName());
            chatRecord.setUserId(MyApplication.getUser().getUserID());
            MyApplication.getChatRecordDao().insert(chatRecord);
            //注册成功以后，需要跳转到标签选择界面，逻辑先放在这里实现，后续需要更改
            showTagFragment();
        }
    }

    /**
     * 和服务器连接，获取本用户的好友通知列表
     */
    private void getFriendInviteList() {
        String url = HttpUtil.URL_GET_USER_INVITE + "?username=" + MyApplication.getUser().getUserName();
        Request request = new Request.Builder().url(url).get().build();
        MyApplication.getClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: getFriendInvite", e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                Log.d(TAG, "onResponse: getFriendInvite" + json);
                TypeToken<List<FriendInvite>> typeToken = new TypeToken<List<FriendInvite>>() {
                };
                List<FriendInvite> friendInviteList = new Gson().fromJson(json, typeToken.getType());
                if (friendInviteList == null) {
                    friendInviteList = new ArrayList<>();
                }
                MyApplication.setFriendInviteList(friendInviteList);
            }
        });
    }

    /**
     * 根据用户信息来填充昵称、签名以及头像
     */
    private void fillViewWithValues(UserInfo userInfo) {
        userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
            @Override
            public void gotResult(int i, String s, Bitmap bitmap) {
                if (bitmap != null) {
                    Glide.with(avatarImage).load(bitmap).into(avatarImage);
                }
            }
        });
        nameText.setText(WillowUtils.getMyNickName());
        signText.setText(WillowUtils.getSignature(userInfo));
    }

    /**
     * BoomMenuButton在xml定义后该界面要马上就进行初始化，不可以在初始化完成前切换到其他界面，否则直接报错
     */
    private void initBoomMenuButton() {
        //这个是 用在addButton展开的按钮上
        addButton = findViewById(R.id.main_add);
        ArrayList<ButtonMessage> buttonMessageList = new ArrayList<>();
        buttonMessageList.add(new ButtonMessage("添加好友", R.drawable.add_contacts_black));
        buttonMessageList.add(new ButtonMessage("测试", R.drawable.user_info_black));
        buttonMessageList.add(new ButtonMessage("文本设置", R.drawable.gesture_black));
        buttonMessageList.add(new ButtonMessage("我的标签", R.drawable.tag_black));
        buttonMessageList.add(new ButtonMessage("好友通知", R.drawable.contacts_apply_black));


        //这里需要让popupWindow show，里面装载有各类更多的按钮
        for (int i = 0; i < addButton.getPiecePlaceEnum().pieceNumber(); i++) {
            ButtonMessage buttonMessage = buttonMessageList.get(i);
            TextInsideCircleButton.Builder builder = new TextInsideCircleButton.Builder()
                    .normalImageRes(buttonMessage.getImageResourceId())
                    .imageRect(new Rect(Util.dp2px(20), Util.dp2px(10), Util.dp2px(60), Util.dp2px(50)))
                    .normalText(buttonMessage.getText())
                    .listener(new OnBMClickListener() {
                        @Override
                        public void onBoomButtonClick(int index) {
                            handleAddButtonEvent(buttonMessage.getText());
                        }
                    });
            addButton.addBuilder(builder);
        }
    }


    private void initListener() {
        avatarImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ViewUtils.showMyFragment();
            }
        });
    }

    private void handleAddButtonEvent(String string) {
        switch (string) {
            case "添加好友":
                //添加好友跳转到的是好友搜索界面
                showSearchFriendFragment();
                break;
            case "我的信息":
                okHttpTest();
                break;
            case "文本设置":
                showCustomTextFragment();
                break;
            case "我的标签":
                showTagFragment();
                break;
            case "好友通知":
                showFriendNotificationFragment();
        }
    }

    private void showTagFragment() {
        String tag = "showTag";
        ShowTagFragment show = (ShowTagFragment) MyApplication.fragmentManager.findFragmentByTag(tag);
        if (show == null) {
            show = new ShowTagFragment();
        }
        show.setUserInfo(MyApplication.getUser());
        Bundle bundle = new Bundle();
        bundle.putInt("isNewUser", 1);
        bundle.putString("backTag", null);
        show.setArguments(bundle);
        ViewUtils.showFragment(show, tag, R.anim.from_right, R.anim.out_right);

    }

    private void showCustomTextFragment() {
        String tag = "customText";
        CustomTextFragment fragment = (CustomTextFragment) MyApplication.fragmentManager.findFragmentByTag(tag);
        if (fragment == null) {
            fragment = new CustomTextFragment();
        }
        fragment.setGestureAndFaceResultList(MyApplication.getGestureAndFaceResultList());
        ViewUtils.showFragment(fragment, tag, R.anim.from_right, R.anim.out_right);

    }

    private void showSearchFriendFragment() {
        String tag = "searchFriend";
        Fragment fragment = MyApplication.fragmentManager.findFragmentByTag(tag);
        if (fragment == null) {
            fragment = new SearchFriendFragment();
        }
        ViewUtils.showFragment(fragment, tag, R.anim.from_right, R.anim.out_right);

    }


    public void initTabLayout() {

        //获得要展示在viewpager的fragment列表，由于展示的fragment是固定不变的，所以直接写死在MyApplication,也方便后续在其他界面直接调用
        List<Fragment> fragmentList = MyApplication.getFragmentList();

        // 创建一个字符串数组，两个int数组，分别存放TabLayout中对每个Fragment的图标(选中以及未选中)和名称，一一对应
        String[] nameArray = {"信息", "联系人", "匹配"};
        int[] iconSelectedArray = {R.drawable.message_selected, R.drawable.contacts_selected, R.drawable.pair};
        int[] iconUnSelectedArray = {R.drawable.message, R.drawable.contacts, R.drawable.pair_grey};

        // 设置viewPager的适配器
        MainPageViewAdapter adapter = new MainPageViewAdapter(getSupportFragmentManager(), fragmentList);
        viewPager.setAdapter(adapter);
        // tabLayout和viewPager联动,tabLayout会自动根据viewPager适配器的getCount，来生成对应数量的tabItem
        tabLayout.setupWithViewPager(viewPager);

        // 遍历itemMessageMap, 往TabLayout里面添加我们需要的自定义布局
        for (int i = 0; i < fragmentList.size(); i++) {
            int icon;
            if (i != 0) {
                icon = iconUnSelectedArray[i];
            } else {
                icon = iconSelectedArray[i];
            }
            tabLayout.getTabAt(i).setCustomView(getCustomTabItemView(nameArray[i], icon));
        }


        // 设置选中监听器，实现选中/未选中状态展示不一样的图片
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                // 获取当前选中的Tab的位置
                int position = tab.getPosition();
                // 在viewPager中设置当前展示的Fragment
                viewPager.setCurrentItem(position);
                View view = tab.getCustomView();
                // 将对应的ImageView设置成选中的图标
                ((ImageView) view.findViewById(R.id.tab_layout_item_icon)).setImageResource(iconSelectedArray[position]);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                // 获取当前选中的Tab的位置
                int position = tab.getPosition();
                View view = tab.getCustomView();
                // 将对应的ImageView设置成未选中的图标
                ((ImageView) view.findViewById(R.id.tab_layout_item_icon)).setImageResource(iconUnSelectedArray[position]);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });

    }

    private View getCustomTabItemView(String name, int icon) {
        View view = LayoutInflater.from(this).inflate(R.layout.layout_tablayout_item, null);
        TextView nameText = view.findViewById(R.id.tab_layout_item_name);
        ImageView imageView = view.findViewById(R.id.tab_layout_item_icon);
        nameText.setText(name);
        imageView.setImageResource(icon);
        return view;
    }

    public void getScreenWidthAndLength() {
        Display display = getWindowManager().getDefaultDisplay();
        MyApplication.ScreenWidth = display.getWidth();
        MyApplication.ScreenHeight = display.getHeight();
    }

    public void okHttpTest() {
        String username = "suyuan";
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        Log.d(TAG, "okHttpTest: " + new Gson().toJson(username) + "\n" + map.toString() + "\n" + new Gson().toJson(map));
    }

    private void getUserIdentifyList() {
        Map<String, String> map = new HashMap<>();
        map.put("username", MyApplication.getUser().getUserName());
        RequestBody requestBody = RequestBody.create(HttpUtil.JSON, new Gson().toJson(map));
        Request request = new Request.Builder().url(HttpUtil.URL_GET_USER_IDENTIFY).post(requestBody).build();
        MyApplication.getClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: ", e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                Log.d(TAG, "onResponse: " + json);
                TypeToken<List<UserIdentify>> typeToken = new TypeToken<List<UserIdentify>>() {
                };
                List<UserIdentify> allUserIdentifyList = new Gson().fromJson(json, typeToken.getType());
                if (allUserIdentifyList == null) {
                    allUserIdentifyList = new ArrayList<>();
                }
                // 根据identifyList和用户的预设文本列表，生成GestureAndFaceResult列表，该列表存储有Identify+该用户该identify的文本
                for (Identify identify : MyApplication.getIdentifyList()) {
                    GestureAndFaceResult result = new GestureAndFaceResult();
                    result.setIdentify(identify);
                    List<UserIdentify> userIdentifyList = new ArrayList<>();
                    // 遍历用户的预设文本列表，将其分类，
                    for (int i = 0; i < allUserIdentifyList.size(); i++) {
                        UserIdentify userIdentify = allUserIdentifyList.get(i);
                        // 如果该预设文本的id和identifyList的id相等，说明二者属于同一个identify
                        if (userIdentify.getIdentifyId().equals(identify.getIdentifyId())) {
                            userIdentifyList.add(userIdentify);
                            allUserIdentifyList.remove(i);
                            i--;
                        }
                    }
                    //分类完添加到result中
                    result.setUserIdentifyList(userIdentifyList);
                    //result再添加到列表中
                    MyApplication.getGestureAndFaceResultList().add(result);
                }

            }
        });
    }

    private void getIdentifyList() {
        Request request = new Request.Builder().url(HttpUtil.URL_GET_ALL_IDENTIFY).get().build();
        MyApplication.getClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: ", e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                Log.d(TAG, "onResponse: " + json);
                TypeToken<List<Identify>> typeToken = new TypeToken<List<Identify>>() {
                };
                List<Identify> identifyList = new Gson().fromJson(json, typeToken.getType());
                if (identifyList == null) {
                    identifyList = new ArrayList<>();
                }
                MyApplication.setIdentifyList(identifyList);
                getUserIdentifyList();
            }
        });
    }

}